home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / ddj0492.zip / DFLT11.ZIP / MENUBAR.C < prev    next >
Text File  |  1992-02-27  |  13KB  |  395 lines

  1. /* ---------------- menubar.c ------------------ */
  2.  
  3. #include "dflat.h"
  4.  
  5. static void reset_menubar(WINDOW);
  6.  
  7. static struct {
  8.     int x1, x2;     /* position in menu bar */
  9.     char sc;        /* shortcut key value   */
  10. } menu[10];
  11. static int mctr;
  12.  
  13. MBAR *ActiveMenuBar;
  14. static MENU *ActiveMenu;
  15.  
  16. static WINDOW mwnd;
  17. static BOOL Selecting;
  18.  
  19. static WINDOW Cascaders[MAXCASCADES];
  20. static int casc;
  21. static WINDOW GetDocFocus(WINDOW);
  22.  
  23. /* ----------- SETFOCUS Message ----------- */
  24. static void SetFocusMsg(WINDOW wnd, PARAM p1)
  25. {
  26.     if (!(int)p1) 
  27.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  28. }
  29.  
  30. /* --------- BUILDMENU Message --------- */
  31. static void BuildMenuMsg(WINDOW wnd, PARAM p1)
  32. {
  33.     int offset = 3;
  34.     reset_menubar(wnd);
  35.     mctr = 0;
  36.     ActiveMenuBar = (MBAR *) p1;
  37.     ActiveMenu = ActiveMenuBar->PullDown;
  38.     while (ActiveMenu->Title != NULL &&
  39.             ActiveMenu->Title != (void*)-1)    {
  40.         char *cp;
  41.         if (strlen(GetText(wnd)+offset) <
  42.                 strlen(ActiveMenu->Title)+3)
  43.             break;
  44.         GetText(wnd) = realloc(GetText(wnd),
  45.             strlen(GetText(wnd))+5);
  46.         memmove(GetText(wnd) + offset+4, GetText(wnd) + offset,
  47.                 strlen(GetText(wnd))-offset+1);
  48.         CopyCommand(GetText(wnd)+offset,ActiveMenu->Title,FALSE,
  49.                 wnd->WindowColors [STD_COLOR] [BG]);
  50.         menu[mctr].x1 = offset;
  51.         offset += strlen(ActiveMenu->Title) + (3+MSPACE);
  52.         menu[mctr].x2 = offset-MSPACE;
  53.         cp = strchr(ActiveMenu->Title, SHORTCUTCHAR);
  54.         if (cp)
  55.             menu[mctr].sc = tolower(*(cp+1));
  56.         mctr++;
  57.         ActiveMenu++;
  58.     }
  59.     ActiveMenu = ActiveMenuBar->PullDown;
  60. }
  61.  
  62. /* ---------- PAINT Message ---------- */
  63. static void PaintMsg(WINDOW wnd)
  64. {
  65.     if (Selecting)
  66.         return;
  67.     if (wnd == inFocus)
  68.         SendMessage(GetParent(wnd), ADDSTATUS, 0, 0);
  69.     SetStandardColor(wnd);
  70.     wputs(wnd, GetText(wnd), 0, 0);
  71.     if (ActiveMenuBar->ActiveSelection != -1 &&
  72.             (wnd == inFocus || mwnd != NULL))    {
  73.         char *sel;
  74.         char *cp;
  75.         if ((sel = malloc(200)) != NULL)    {
  76.             int offset=menu[ActiveMenuBar->ActiveSelection].x1;
  77.             int offset1=menu[ActiveMenuBar->ActiveSelection].x2;
  78.             GetText(wnd)[offset1] = '\0';
  79.             SetReverseColor(wnd);
  80.             memset(sel, '\0', 200);
  81.             strcpy(sel, GetText(wnd)+offset);
  82.             cp = strchr(sel, CHANGECOLOR);
  83.             if (cp != NULL)
  84.                 *(cp + 2) = background | 0x80;
  85.             wputs(wnd, sel,
  86.                 offset-ActiveMenuBar->ActiveSelection*4, 0);
  87.             GetText(wnd)[offset1] = ' ';
  88.             if (mwnd == NULL && wnd == inFocus) {
  89.                 char *st = ActiveMenu
  90.                     [ActiveMenuBar->ActiveSelection].StatusText;
  91.                 if (st != NULL)
  92.                     SendMessage(GetParent(wnd), ADDSTATUS,
  93.                         (PARAM)st, 0);
  94.             }
  95.             free(sel);
  96.         }
  97.     }
  98. }
  99.  
  100. /* ------------ KEYBOARD Message ------------- */
  101. static void KeyboardMsg(WINDOW wnd, PARAM p1)
  102. {
  103.     MENU *mnu;
  104.     if (mwnd == NULL)    {
  105.         /* ----- search for menu bar shortcut keys ---- */
  106.         int c = tolower((int)p1);
  107.         int a = AltConvert((int)p1);
  108.         int j;
  109.         for (j = 0; j < mctr; j++)    {
  110.             if ((inFocus == wnd && menu[j].sc == c) ||
  111.                     (a && menu[j].sc == a))    {
  112.                 SendMessage(wnd, MB_SELECTION, j, 0);
  113.                 return;
  114.             }
  115.         }
  116.     }
  117.     /* -------- search for accelerator keys -------- */
  118.     mnu = ActiveMenu;
  119.     while (mnu->Title != (void *)-1)    {
  120.         struct PopDown *pd = mnu->Selections;
  121.         if (mnu->PrepMenu)
  122.             (*(mnu->PrepMenu))(GetDocFocus(wnd), mnu);
  123.         while (pd->SelectionTitle != NULL)    {
  124.             if (pd->Accelerator == (int) p1)    {
  125.                 if (pd->Attrib & INACTIVE)
  126.                     beep();
  127.                 else    {
  128.                     if (pd->Attrib & TOGGLE)
  129.                         pd->Attrib ^= CHECKED;
  130.                     SendMessage(GetDocFocus(wnd),
  131.                         SETFOCUS, TRUE, 0);
  132.                     PostMessage(GetParent(wnd),
  133.                         COMMAND, pd->ActionId, 0);
  134.                 }
  135.                 return;
  136.             }
  137.             pd++;
  138.         }
  139.         mnu++;
  140.     }
  141.     switch ((int)p1)    {
  142.         case F1:
  143.             if (ActiveMenu != NULL &&
  144.                 (mwnd == NULL ||
  145.                 (ActiveMenu+ActiveMenuBar->ActiveSelection)->
  146.                     Selections[0].SelectionTitle == NULL)) {
  147.                 DisplayHelp(wnd,
  148.         (ActiveMenu+ActiveMenuBar->ActiveSelection)->Title+1);
  149.                 return;
  150.             }
  151.             break;
  152.         case '\r':
  153.             if (mwnd == NULL &&
  154.                     ActiveMenuBar->ActiveSelection != -1)
  155.                 SendMessage(wnd, MB_SELECTION,
  156.                     ActiveMenuBar->ActiveSelection, 0);
  157.             break;
  158.         case F10:
  159.             if (wnd != inFocus && mwnd == NULL)    {
  160.                 SendMessage(wnd, SETFOCUS, TRUE, 0);
  161.                 if ( ActiveMenuBar->ActiveSelection == -1)
  162.                     ActiveMenuBar->ActiveSelection = 0;
  163.                 SendMessage(wnd, PAINT, 0, 0);
  164.                 break;
  165.             }
  166.             /* ------- fall through ------- */
  167.         case ESC:
  168.             if (inFocus == wnd && mwnd == NULL)    {
  169.                 ActiveMenuBar->ActiveSelection = -1;
  170.                 SendMessage(GetDocFocus(wnd),SETFOCUS,TRUE,0);
  171.                 SendMessage(wnd, PAINT, 0, 0);
  172.             }
  173.             break;
  174.         case FWD:
  175.             ActiveMenuBar->ActiveSelection++;
  176.             if (ActiveMenuBar->ActiveSelection == mctr)
  177.                 ActiveMenuBar->ActiveSelection = 0;
  178.             if (mwnd != NULL)
  179.                 SendMessage(wnd, MB_SELECTION,
  180.                     ActiveMenuBar->ActiveSelection, 0);
  181.             else 
  182.                 SendMessage(wnd, PAINT, 0, 0);
  183.             break;
  184.         case BS:
  185.             if (ActiveMenuBar->ActiveSelection == 0)
  186.                 ActiveMenuBar->ActiveSelection = mctr;
  187.             --ActiveMenuBar->ActiveSelection;
  188.             if (mwnd != NULL)
  189.                 SendMessage(wnd, MB_SELECTION,
  190.                     ActiveMenuBar->ActiveSelection, 0);
  191.             else 
  192.                 SendMessage(wnd, PAINT, 0, 0);
  193.             break;
  194.         default:
  195.             break;
  196.     }
  197. }
  198.  
  199. /* --------------- LEFT_BUTTON Message ---------- */
  200. static void LeftButtonMsg(WINDOW wnd, PARAM p1)
  201. {
  202.     int i;
  203.     int mx = (int) p1 - GetLeft(wnd);
  204.     /* --- compute the selection that the left button hit --- */
  205.     for (i = 0; i < mctr; i++)
  206.         if (mx >= menu[i].x1-4*i &&
  207.                 mx <= menu[i].x2-4*i-5)
  208.             break;
  209.     if (i < mctr)
  210.         if (i != ActiveMenuBar->ActiveSelection || mwnd == NULL)
  211.             SendMessage(wnd, MB_SELECTION, i, 0);
  212. }
  213.  
  214. /* -------------- MB_SELECTION Message -------------- */
  215. static void SelectionMsg(WINDOW wnd, PARAM p1, PARAM p2)
  216. {
  217.     int wd, mx, my;
  218.     MENU *mnu;
  219.  
  220.     if (!p2)    {
  221.         ActiveMenuBar->ActiveSelection = -1;
  222.         SendMessage(wnd, PAINT, 0, 0);
  223.     }
  224.     Selecting = TRUE;
  225.     mnu = ActiveMenu+(int)p1;
  226.     if (mnu->PrepMenu != NULL)
  227.         (*(mnu->PrepMenu))(GetDocFocus(wnd), mnu);
  228.     wd = MenuWidth(mnu->Selections);
  229.     if (p2)    {
  230.         mx = GetLeft(mwnd) + WindowWidth(mwnd) - 1;
  231.         my = GetTop(mwnd) + mwnd->selection;
  232.     }
  233.     else    {
  234.         int offset = menu[(int)p1].x1 - 4 * (int)p1;
  235.         if (mwnd != NULL)
  236.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  237.         ActiveMenuBar->ActiveSelection = (int) p1;
  238.         if (offset > WindowWidth(wnd)-wd)
  239.             offset = WindowWidth(wnd)-wd;
  240.         mx = GetLeft(wnd)+offset;
  241.         my = GetTop(wnd)+1;
  242.     }
  243.     mwnd = CreateWindow(POPDOWNMENU, NULL,
  244.                 mx, my,
  245.                 MenuHeight(mnu->Selections),
  246.                 wd,
  247.                 NULL,
  248.                 wnd,
  249.                 NULL,
  250.                 0);
  251.     AddAttribute(mwnd, SHADOW);
  252.     if (!p2)    {
  253.         Selecting = FALSE;
  254.         SendMessage(wnd, PAINT, 0, 0);
  255.         Selecting = TRUE;
  256.     }
  257.     if (mnu->Selections[0].SelectionTitle != NULL)    {
  258.         SendMessage(mwnd, BUILD_SELECTIONS, (PARAM) mnu, 0);
  259.         SendMessage(mwnd, SHOW_WINDOW, 0, 0);
  260.     }
  261.     Selecting = FALSE;
  262. }
  263.  
  264. /* --------- COMMAND Message ---------- */
  265. static void CommandMsg(WINDOW wnd, PARAM p1, PARAM p2)
  266. {
  267.     if (isCascadedCommand(ActiveMenuBar, (int)p1))    {
  268.         /* find the cascaded menu based on command id in p1 */
  269.         MENU *mnu = ActiveMenu+mctr;
  270.         while (mnu->Title != (void *)-1)    {
  271.             if (mnu->CascadeId == (int) p1)    {
  272.                 if (casc < MAXCASCADES)    {
  273.                     Cascaders[casc++] = mwnd;
  274.                     SendMessage(wnd, MB_SELECTION,
  275.                         (PARAM)(mnu-ActiveMenu), TRUE);
  276.                 }
  277.                 break;
  278.             }
  279.             mnu++;
  280.         }
  281.     }
  282.     else     {
  283.         if (mwnd != NULL)
  284.             SendMessage(mwnd, CLOSE_WINDOW, 0, 0);
  285.         SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  286.         PostMessage(GetParent(wnd), COMMAND, p1, p2);
  287.     }
  288. }
  289.  
  290. /* --------------- CLOSE_POPDOWN Message --------------- */
  291. static void ClosePopdownMsg(WINDOW wnd)
  292. {
  293.     if (casc > 0)
  294.         SendMessage(Cascaders[--casc], CLOSE_WINDOW, 0, 0);
  295.     else     {
  296.         mwnd = NULL;
  297.         ActiveMenuBar->ActiveSelection = -1;
  298.         if (!Selecting)    {
  299.             SendMessage(GetDocFocus(wnd), SETFOCUS, TRUE, 0);
  300.             SendMessage(wnd, PAINT, 0, 0);
  301.         }
  302.     }
  303. }
  304.  
  305. /* ---------------- CLOSE_WINDOW Message --------------- */
  306. static void CloseWindowMsg(WINDOW wnd)
  307. {
  308.     if (GetText(wnd) != NULL)    {
  309.         free(GetText(wnd));
  310.         GetText(wnd) = NULL;
  311.     }
  312.     mctr = 0;
  313.     ActiveMenuBar->ActiveSelection = -1;
  314.     ActiveMenu = NULL;
  315.     ActiveMenuBar = NULL;
  316. }
  317.  
  318. /* --- Window processing module for MENUBAR window class --- */
  319. int MenuBarProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  320. {
  321.     int rtn;
  322.  
  323.     switch (msg)    {
  324.         case CREATE_WINDOW:
  325.             reset_menubar(wnd);
  326.             break;
  327.         case SETFOCUS:
  328.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  329.             SetFocusMsg(wnd, p1);
  330.             return rtn;
  331.         case BUILDMENU:
  332.             BuildMenuMsg(wnd, p1);
  333.             break;
  334.         case PAINT:    
  335.             if (!isVisible(wnd) || GetText(wnd) == NULL)
  336.                 break;
  337.             PaintMsg(wnd);
  338.             return FALSE;
  339.         case BORDER:
  340.             return TRUE;
  341.         case KEYBOARD:
  342.             KeyboardMsg(wnd, p1);
  343.             return TRUE;
  344.         case LEFT_BUTTON:
  345.             LeftButtonMsg(wnd, p1);
  346.             return TRUE;
  347.         case MB_SELECTION:
  348.             SelectionMsg(wnd, p1, p2);
  349.             break;
  350.         case COMMAND:
  351.             CommandMsg(wnd, p1, p2);
  352.             return TRUE;
  353.         case INSIDE_WINDOW:
  354.             return InsideRect(p1, p2, WindowRect(wnd));
  355.         case CLOSE_POPDOWN:
  356.             ClosePopdownMsg(wnd);
  357.             return TRUE;
  358.         case CLOSE_WINDOW:
  359.             rtn = BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  360.             CloseWindowMsg(wnd);
  361.             return rtn;
  362.         default:
  363.             break;
  364.     }
  365.     return BaseWndProc(MENUBAR, wnd, msg, p1, p2);
  366. }
  367.  
  368. /* ----- return the WINDOW handle of the document window
  369.      that had the focus when the MENUBAR was activated ----- */
  370. static WINDOW GetDocFocus(WINDOW wnd)
  371. {
  372.     WINDOW DocFocus = Focus.LastWindow;
  373.     CLASS cl;
  374.     while ((cl = GetClass(DocFocus)) == MENUBAR ||
  375.                 cl == POPDOWNMENU ||
  376.                     cl == STATUSBAR ||
  377.                         cl == APPLICATION)                    {
  378.         if ((DocFocus = PrevWindow(DocFocus)) == NULL)    {
  379.             DocFocus = GetParent(wnd);
  380.             break;
  381.         }
  382.     }
  383.     return DocFocus;
  384. }
  385.  
  386. /* ------------- reset the MENUBAR -------------- */
  387. static void reset_menubar(WINDOW wnd)
  388. {
  389.     if ((GetText(wnd) =
  390.             realloc(GetText(wnd), SCREENWIDTH+5)) != NULL)    {
  391.         memset(GetText(wnd), ' ', SCREENWIDTH);
  392.         *(GetText(wnd)+WindowWidth(wnd)) = '\0';
  393.     }
  394. }
  395.